在構建企業開發規範 RAG(檢索增強生成)管線時,向量資料庫(Vector Database)扮演著核心記憶庫的角色。通用大模型無法掌握企業內部最新或專屬的 Coding Style、Git 分支流程與 API 設計規範;唯有透過向量資料庫將規範文件高效索引,才能在推論時提供精準的上下文依據。
今天我們將評估企業常見的向量資料庫選型,並使用 Qdrant 完成本地容器化搭建,同時完成企業規範專用的集合(Collections)與 Metadata Payload 結構設計。
| 評估維度 | Qdrant | Milvus | PGVector (PostgreSQL) | Chroma |
|---|---|---|---|---|
| 實作語言 | Rust(效能與記憶體安全高) | Go / C++ | C (Postgres Extension) | Python |
| 部署複雜度 | 低(單一 Binary / 輕量 Docker) | 較高(依賴 etcd、MinIO 等元件) | 極低(直接沿用既有 PG 集群) | 極低(適合本地嵌入式開發) |
| Metadata 過濾能力 | 極強(支援豐富 Payload 索引) | 強 | 強(依賴標準 SQL 語法) | 基礎 |
| 資源消耗 | 輕量、記憶體管理優秀 | 中等偏高(適合超大規模分散式) | 視既有 DB 負載而定 | 極輕量 |
| 生產環境適用度 | 高(企業獨立部署首選) | 高(超大規模分散式首選) | 高(架構輕量化首選) | 偏低(較適合 PoC 實驗階段) |
使用 Docker 建立具備資料持久化(Data Persistence)的 Qdrant 服務。
建立 docker-compose.qdrant.yml:
version: '3.8'
services:
qdrant:
image: qdrant/qdrant:v1.9.0
container_name: enterprise_qdrant
restart: always
ports:
- "6333:6333" # REST API 介面與 Web UI
- "6334:6334" # gRPC 高效傳輸介面
volumes:
- ./qdrant_storage:/qdrant/storage
environment:
- QDRANT__SERVICE__ENABLE_CORS=true
啟動服務:
docker compose -f docker-compose.qdrant.yml up -d
啟動後,可使用瀏覽器開啟 http://localhost:6333/dashboard,進入 Qdrant 內建的視覺化管理介面(Web Dashboard)。
為了讓 RAG 檢索時能快速縮小範圍,避免「Python 規範與 Java 規範混淆」,必須嚴格設計 Payload Metadata。
{
"doc_id": "GUID 或文件識別碼",
"title": "章節或規則標題(例如:RESTful API 命名規範)",
"category": "分類(例如:coding_style, git_flow, api_schema, security)",
"language": "適用程式語言(例如:python, typescript, java, all)",
"version": "適用版本(例如:v1.2.0)",
"source_url": "內部文件 Wiki / Git 連結(用於回覆出處標註)",
"content": "切塊後的文字與程式碼區塊內容"
}
安裝 Python Client:
pip install qdrant-client
建立 init_qdrant.py,配置集合向量維度(以即將採用的 1024 維開源 Embedding 模型為例),並為關鍵欄位建立 Payload Index 以加速後續條件過濾:
from qdrant_client import QdrantClient
from qdrant_client.http import models
# 初始化客戶端(連接本地 6333 埠)
client = QdrantClient(url="http://localhost:6333")
COLLECTION_NAME = "enterprise_dev_standards"
def setup_vector_store():
# 1. 檢查集合是否存在,若不存在則建立
collections = client.get_collections().collections
collection_names = [col.name for col in collections]
if COLLECTION_NAME in collection_names:
print(f"集合 [{COLLECTION_NAME}] 已存在,略過建立步驟。")
return
print(f"正在建立集合: {COLLECTION_NAME}...")
client.create_collection(
collection_name=COLLECTION_NAME,
vectors_config=models.VectorParams(
size=1024, # 向量維度需與 Embedding 模型嚴格一致
distance=models.Distance.COSINE # 餘弦相似度
),
# 啟用 HNSW 索引優化檢索吞吐
hnsw_config=models.HnswConfigDiff(
m=16,
ef_construct=100
)
)
# 2. 建立 Payload 索引,加速精準 Metadata 過濾
print("正在建立 Payload 篩選索引...")
indexed_fields = [
("category", models.PayloadSchemaType.KEYWORD),
("language", models.PayloadSchemaType.KEYWORD),
("version", models.PayloadSchemaType.KEYWORD)
]
for field_name, field_type in indexed_fields:
client.create_payload_index(
collection_name=COLLECTION_NAME,
field_name=field_name,
field_schema=field_type
)
print(f"集合 [{COLLECTION_NAME}] 初始化完成,各項 Payload 索引建立完畢!")
if __name__ == "__main__":
setup_vector_store()
撰寫 verify_qdrant.py,模擬寫入一筆開發規範並執行帶 Metadata 過濾條件的向量檢索:
import numpy as np
from qdrant_client import QdrantClient
from qdrant_client.http import models
client = QdrantClient(url="http://localhost:6333")
COLLECTION_NAME = "enterprise_dev_standards"
# 1. 模擬插入一筆開發規範向量
mock_vector = np.random.rand(1024).tolist()
client.upsert(
collection_name=COLLECTION_NAME,
points=[
models.PointStruct(
id=1,
vector=mock_vector,
payload={
"doc_id": "REST-001",
"title": "RESTful 資源路徑命名指引",
"category": "api_schema",
"language": "all",
"version": "v1.0",
"source_url": "[https://wiki.corp.internal/standards/api-naming](https://wiki.corp.internal/standards/api-naming)",
"content": "所有 API 端點路徑必須使用複數名詞與小寫字母,例如 /api/v1/users,嚴禁使用動詞。"
}
)
]
)
print("測試向量寫入成功!")
# 2. 帶條件的過濾查詢測試
query_vector = np.random.rand(1024).tolist()
search_result = client.search(
collection_name=COLLECTION_NAME,
query_vector=query_vector,
query_filter=models.Filter(
must=[
models.FieldCondition(
key="category",
match=models.MatchValue(value="api_schema")
)
]
),
limit=1
)
print("\n--- 過濾檢索結果 ---")
for hit in search_result:
print(f"評分 (Score): {hit.score:.4f}")
print(f"標題: {hit.payload['title']}")
print(f"內容: {hit.payload['content']}")
向量維度一致性:VectorParams 中的 size 必須與後續選用的 Embedding 模型完全相符(例如 BGE-Large 為 1024 維,OpenAI text-embedding-3-small 為 1536 維),一旦建立即無法中途變更。
Payload 索引效益:若未針對 category 或 language 建立 Payload 索引,隨著企業文件累積到數萬筆時,帶條件的混合篩選將退化為全表暴力掃描,拖慢 RAG 檢索延遲。
向量資料庫與 Metadata 規範已就位。明天 Day 07 我們將進入第一週的最後一天:Embedding 與 Reranker 模型落地,實測開源 Embedding 模型在技術文件上的語義表現,並在本地部署 Cross-Encoder Reranker 服務。